# Password Generator with Python
**How to make a password generator with python and its modules argparse and random**

## Idea
In this tutorial, we will make a Command-line tool for generating passwords. We will use the argparse module to make it easier to parse the command line arguments the user has provided. We make it so the user can define the letters which should be included, how many passwords should be created and if they shall be saved to a .txt file.

Let us get started.

## Imports
Let us import some Modules. For this program, we just need the `ArgumentParser` Class from `argparse` and the `shuffle()` and `choice()` functions from `random`. We also get the `string` module, which has some letters and numbers collections. We don't have to install any of these because they come with python. 

```python
from argparse import ArgumentParser
from random import shuffle, choice
import string
```

## Setting up the argument parser.

Now we continue with setting up the argument parser. To do this we sav,e a new instance of the `ArgumentParser` class to our `parser` variable. We give the parser a name and a description. This information will appear if the user provides the `-h` argument when running our program, it will also tell them the possible arguments.

```python
# Setting up the Argument Parser
parser = ArgumentParser(
    prog='Password Generator.',
    description='Generate any number of passwords with this tool.'
)
```

We continue by adding arguments to the parser. The first four will be the amounts of each character type. That's why we set them all to 2 by default. We check if they are of type integer.

```python
# Adding the arguments to the parser
parser.add_argument('-numNumbers', default=2, type=int)
parser.add_argument('-numLowercaseLetters', default=2, type=int)
parser.add_argument('-numCapitalLetters', default=2, type=int)
parser.add_argument('-numSpecialChars', default=2, type=int)
```

The subsequent two arguments are the desired length and the number of passwords. We set the length to be eight by default because most platforms have this requirement. We check for the length and amount if it is of type int because a string or float would not make sense in this case. The store argument is a flag that just tells the program whether to store the passwords in a text file or not. By default, this is false that is why the action is `"store_true"`.

```python
# The amount is a number so we check it to be of type int.
parser.add_argument('-amount', default=1, type=int)
parser.add_argument('-store', default=False, action='store_true')
```

Last but not least we parse the command line for these arguments with the `parse_args()` method of the `ArgumentParser` class. If we don't call this method the parser won't check for anything and won't raise any exceptions.

```python
# Parsing the command line arguments.
arguments = parser.parse_args()
```

## The Password Loop

We continue with the main part of the program: the Password loop. Here we generate the number of passwords specified by the user.

That is why we define a passwords list that will hold all the generated passwords. We don't need the number which is returned by the range generator.

```python
passwords = []

# Looping through the number of passwords.
for _ in range(int(arguments.amount)):
```

After that, we make a password list which will first hold all the possible letters and then the password string.

```python
password = []
```

Now we add the possible letters, numbers, and special characters to the password list. For each of the types, we check if it is true in the namespace of the parser. We get the respective letters from the string module.

```python
	# If / how many Numbers the password should contain
	for _ in range(arguments.numNumbers):
		password.append(choice(string.digits))

	# If / how many Capital Characters the password should contain
	for _ in range(arguments.numCapitalLetters):
		password.append(choice(string.ascii_uppercase))

	# If / how many lowercase Characters the password should contain
	for _ in range(arguments.numLowercaseLetters):
		password.append(choice(string.ascii_lowercase))

	# If / how many Special Characters the password should contain
	for _ in range(arguments.numSpecialChars):
		password.append(choice(string.punctuation))
```

Then we use the `shuffle` function from `random` to mix up the list. This is done in place.

```python
	# Shuffle the list with all the possible letters, numbers, and symbols.
    shuffle(password)
```

After this, we get the first items of the list until the length specified by the user and then we join the resulting with `""` so we have the string version of it.

```python
    # Get the letters of the string up to the length argument and then join them.
    password = ''.join(password)
```

Last but not least we append this password to the passwords list.

```python
    # Append this password to the overall list of passwords.
    passwords.append(password)
```

## Saving the Passwords

After the password loop, we check if the user said he or she wanted to save the passwords to a file. if that is the case we simply open a file, which will be made if it does not exist.

```python
# Store the password to a .txt file.
if arguments.store:
    with open('passwords.txt', 'w') as f:
        f.write('\n'.join(passwords))
```

In all cases, we print out the passwords.

```python
print('\n'.join(passwords))
```


## Examples

Now you will see some useful examples of the generator. Keep in mind this will be different for you.

```
C:\Users\Maxim> main.py
^G~0,NU4
```
```
C:\Users\Maxim> main.py -amount 5
j@BJk#IO
F~§!]G_E
nGg#MAW-
fh=5c)-§
cjFPy?]A
```
```
C:\Users\Maxim> main.py -amount 2
1*~G^n%K
2ouVq)ç¬
```
```
C:\Users\Maxim> main.py -numCapitalLetters 6
O1AdJ]FQmR&7
```
## Imports

## Setting up the argument parser.

## Specifying the possible characters.

**show trick to speed up process**

## The Password Loop

## Saving the Passwords

## Conclusion

Excellent! You have successfully created a Password Generator using Python code! See how you can add more features to this program such as hashing the passwords or more options.
